package cqrtplm.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONObject;
import com.hustcad.plm.basic.util.TyplmEntityBaseUtil;
import com.hustcad.plm.pdm.common.model.dto.DeleteDTO;
import com.hustcad.plm.pdm.common.service.CommonDeleteService;
import com.hustcad.plm.pdm.doc.service.TyplmDocumentService;
import com.hustcad.plm.pdm.doc.vo.DocumentVO;
import com.hustcad.plm.pdm.ec.module.dto.ECObjData;
import com.hustcad.plm.pdm.ec.module.vo.ChgActivityVO;
import com.hustcad.plm.pdm.ec.module.vo.ChgFormVO;
import com.hustcad.plm.pdm.ec.module.vo.ECObjDataVO;
import com.hustcad.plm.pdm.ec.service.*;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowChgFormView;
import com.hustcad.plm.pdm.middle.partbom.service.TyplmPdmPartService;
import com.hustcad.plm.pdm.workflow.model.entity.WorkFlowContainer;
import com.hustcad.plm.pdm.workflow.model.entity.WorkFlowContainerView;
import com.hustcad.plm.pdm.workflow.service.TyplmWorkFlowContainerDatabaseServiceExt;
import com.hustcad.plm.pdm.workflow.service.TyplmWorkFlowContainerService;
import com.hustcad.plm.pdm.workflow.service.TyplmWorkFlowContainerViewService;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.entity.CTyEntityBaseDO;
import com.ty.basic.entity.IdentifierEntity;
import com.ty.basic.entity.change.ChgActRecordLinkDO;
import com.ty.basic.entity.change.ChgActRelDataLinkDO;
import com.ty.basic.entity.change.ChgActivityDO;
import com.ty.basic.entity.change.ChgNoticeDO;
import com.ty.basic.entity.org.UserDO;
import com.ty.basic.entity.part.PartDO;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import com.ty.basic.session.TyAccountContext;
import cqrtplm.constant.RTPlmConstant;
import cqrtplm.mapper.RTChangeMapper;
import cqrtplm.service.RTResetChgActivityService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RTResetChgActivityServiceImpl implements RTResetChgActivityService {
    private static final int MAX_RETRY = 150; //设置最大重试次数防止死循环
    @Resource
    private TyplmWorkFlowContainerService typlmWorkFlowContainerService;
    @Resource
    private TyplmChgActivityService typlmChgActivityService;
    @Resource
    private TyplmChgActRecordLinkService typlmChgActRecordLinkService;
    @Resource
    private TyplmChgNoticeActivityLinkService typlmChgNoticeActivityLinkService;
    @Resource
    private TyplmChgActRelDataLinkService typlmChgActRelDataLinkService;
    @Resource
    private CommonDeleteService commonDeleteService;
    @Resource
    private RTChangeMapper rtChangeMapper;
    @Resource
    private TyplmPdmPartService typlmPdmPartService;
    @Resource
    private TyplmDocumentService typlmDocumentService;
    @Resource
    private SnowflakeIdComponent snowflakeIdComponent;
    @Resource
    private TyplmChangeObjectLinkService typlmChangeObjectLinkService;
    @Resource
    private PlatformTransactionManager platformTransactionManager;
    @Resource
    private TyplmWorkFlowContainerViewService typlmWorkFlowContainerViewService;
    @Resource
    private TyplmWorkFlowContainerDatabaseServiceExt typlmWorkFlowContainerDatabaseServiceExt;
    @Autowired
    private TyplmChgNoticeService typlmChgNoticeService;

    /**
     * 重置变更子任务
     *
     * @param workFlowContainerId
     */
    @Override
    public void resetChgActivity(String workFlowContainerId) {
        List<String> errorList = new ArrayList();
        TyAccountContext.setIgnoreAuth(true);
        UserDO userDO = TyAccountContext.getUser();
        DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
        defaultTransactionDefinition.setPropagationBehavior(3);
        TransactionStatus transaction = this.platformTransactionManager.getTransaction(defaultTransactionDefinition);
        WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(new BigInteger(workFlowContainerId));
        try {
            StringBuffer sb = null;
            if (!Objects.isNull(workFlowContainerView) && workFlowContainerView instanceof FlowChgFormView) {
                if (workFlowContainerView instanceof FlowChgFormView) {
                    log.info("当前流程属于变更通告流程");
                    FlowChgFormView flowChgFormView = (FlowChgFormView) workFlowContainerView;
                    ChgFormVO chgFormVO = flowChgFormView.getChgFormVO();
                    String changeNo = chgFormVO.getObjectNumber();
                    List<ECObjData> aecObjDataVOS = chgFormVO.getEcAffectVOS();
                    List<ECObjData> becObjDataVOS = chgFormVO.getEcObjDataVOS();
                    if (changeNo.contains("RTTJXM")) {
                        //修模通知单
                    } else if (changeNo.contains("RTTJJG")) {
                        //订单更改通知单
                    } else if (changeNo.contains("RTTJST")) {
                        //设计更改通知单
                        List<ChgActivityDO> chgActivityDOList = this.typlmChgNoticeActivityLinkService.queryECAByECNId(chgFormVO.getOid());
                        List<ChgActRelDataLinkDO> beforeDataLinkDOList = new ArrayList();
                        List<ChgActRecordLinkDO> afterDataLinkDOList = new ArrayList();
                        List<ECObjDataVO> beforeDataLinkList = new ArrayList();
                        List<ECObjDataVO> afterDataLinkList = new ArrayList();
                        List<BigInteger> deleteWFContainerIdList = new ArrayList<>();
                        List<WorkFlowContainer> deleteWFContainerList = new ArrayList<>();
                        List<ChgActivityDO> deleteList = new ArrayList<>();
                        List<BigInteger> deleteEcaBranchList = new ArrayList<>();
                        ChgActivityDO chgActivityDO = null;
                        if (CollUtil.isNotEmpty(chgActivityDOList)) {
                            for (ChgActivityDO activityDO : chgActivityDOList) {
                                String desc = activityDO.getDescription();
                                if (StringUtils.isBlank(desc)) {
                                    chgActivityDO = activityDO;
                                } else {
                                    if ("图文档".equals(desc)) {
                                        beforeDataLinkList = this.typlmChangeObjectLinkService.queryECObjList(new IdentifierEntity(activityDO.getOid(), activityDO.getOtype()), Boolean.TRUE);
                                        afterDataLinkList = this.typlmChangeObjectLinkService.queryECObjList(new IdentifierEntity(activityDO.getOid(), activityDO.getOtype()), Boolean.FALSE);
                                        List<WorkFlowContainer> containers = typlmWorkFlowContainerService.batchQueryWorkFlowContainerByBaseObj(Arrays.asList(activityDO.getOid()), activityDO.getOtype());
                                        deleteEcaBranchList.add(activityDO.getBranchid());
                                        if (CollUtil.isNotEmpty(containers)){
                                            deleteWFContainerIdList.addAll(containers.stream().map(WorkFlowContainer::getOid).collect(Collectors.toList()));
                                            deleteWFContainerList.addAll(containers);
                                        }
                                        deleteList.add(activityDO);
                                    }
                                }
                            }
                        }
                        if (chgActivityDO != null) {
                            if (CollUtil.isNotEmpty(deleteWFContainerIdList)&&CollUtil.isNotEmpty(deleteWFContainerList)) {
                                //删除系统自动创建的变更子任务的流程
                                this.typlmWorkFlowContainerDatabaseServiceExt.delete(deleteWFContainerIdList);
                                this.typlmWorkFlowContainerViewService.delete(deleteWFContainerIdList, deleteWFContainerList);
                            }
                            if (CollUtil.isNotEmpty(deleteEcaBranchList)) {
                                ChgNoticeDO noticeDO =typlmChgNoticeService.selectByPrimaryKey(chgFormVO.getOid());
                                for (BigInteger ecaBranchId : deleteEcaBranchList){
                                    //删除ECN与ECA的关联关系
                                    this.typlmChgNoticeActivityLinkService.deleteLinkByEcoBranchIdAndEcaBranchId(noticeDO.getBranchid(),ecaBranchId);
                                }
                                //删除变更前和变更后对象
                                this.typlmChgActRelDataLinkService.batchDeleteChgRelDataLinkByECA(deleteEcaBranchList);
                                this.typlmChgActRecordLinkService.batchDeleteChgRecLinkByECA(deleteEcaBranchList);
                            }
                            if (CollUtil.isNotEmpty(deleteList)) {
                                //删除系统自动创建的变更子任务
                                this.typlmChgActivityService.batchDeleteEca(Convert.toList(ChgActivityVO.class, deleteList));
                            }
                            //添加变更后对象
                            if (CollUtil.isNotEmpty(afterDataLinkList)) {
                                List<ChgActRecordLinkDO> chgActRecordLinkDOList = new ArrayList<>();
                                for (ECObjDataVO ecObjDataVO : afterDataLinkList) {
                                    ChgActRecordLinkDO chgActRecordLinkDO = new ChgActRecordLinkDO();
                                    chgActRecordLinkDO.setAoid(chgActivityDO.getOid());
                                    chgActRecordLinkDO.setAotype(chgActivityDO.getOtype());
                                    chgActRecordLinkDO.setBoid(ecObjDataVO.getOid());
                                    chgActRecordLinkDO.setBotype(ecObjDataVO.getOtype());
                                    chgActRecordLinkDO.setOid(snowflakeIdComponent.getInstance().nextId());
                                    chgActRecordLinkDO.setOtype(TableTypeConstrant.TY_CHGACTRECORDLINK_OTYPE);
                                    chgActRecordLinkDO.setBranchid(chgActivityDO.getBranchid());
                                    TyplmEntityBaseUtil.fillCommonFieldForCreate(chgActRecordLinkDO);
                                    chgActRecordLinkDOList.add(chgActRecordLinkDO);
                                }
                                if (CollUtil.isNotEmpty(chgActRecordLinkDOList))
                                    this.typlmChgActRecordLinkService.batchInsertSelective(chgActRecordLinkDOList);
                            }
                            //添加变更前对象
                            if (CollUtil.isNotEmpty(beforeDataLinkList)) {
                                List<ChgActRelDataLinkDO> actRelDataLinkDOList = new ArrayList<>();
                                for (ECObjDataVO ecObjDataVO : beforeDataLinkList) {
                                    ChgActRelDataLinkDO linkDO = new ChgActRelDataLinkDO();
                                    linkDO.setBoid(ecObjDataVO.getOid());
                                    linkDO.setBotype(ecObjDataVO.getOtype());
                                    linkDO.setAoid(chgActivityDO.getOid());
                                    linkDO.setAotype(chgActivityDO.getOtype());
                                    linkDO.setBranchid(chgActivityDO.getBranchid());
                                    linkDO.setOwneroid(ecObjDataVO.getOwneroid());
                                    linkDO.setOwnerotype(TableTypeConstrant.TY_USER_OTYPE);
                                    linkDO.setChangestrategy("Change");
                                    linkDO.setOid(snowflakeIdComponent.getInstance().nextId());
                                    linkDO.setOtype(TableTypeConstrant.TY_CHGACTRELDATALINK_OTYPE);
                                    TyplmEntityBaseUtil.fillCommonFieldForCreate(linkDO,new Date());
                                    actRelDataLinkDOList.add(linkDO);
                                }
                                if (CollUtil.isNotEmpty(actRelDataLinkDOList))
                                    this.typlmChgActRelDataLinkService.batchInsertSelective(actRelDataLinkDOList);
//                                for (ECObjDataVO ecObjDataVO : beforeDataLinkList) {
//                                    ECObjDTO entity = new ECObjDTO();
//                                    entity.setOid(ecObjDataVO.getOid());
//                                    entity.setOtype(ecObjDataVO.getOtype());
//                                    entity.setOwnerOid(ecObjDataVO.getOwneroid());
//                                    entity.setOwnerOtype(TableTypeConstrant.TY_USER_OTYPE);
//                                    entity.setChangeStrategy("Change");
//                                    entity.setIdentifierRef(new IdentifierEntity(ecObjDataVO.getOid(), ecObjDataVO.getOtype()));
//                                    entityList.add(entity);
//                                }
//                                if (CollUtil.isNotEmpty(entityList)) {
//                                    ECAddChangeObjectDTO ecAddChangeObjectDTO = new ECAddChangeObjectDTO();
//                                    ecAddChangeObjectDTO.setEntityList(entityList);
//                                    ecAddChangeObjectDTO.setBefore(true);
//                                    ecAddChangeObjectDTO.setSaveDataBase(false);
//                                    ecAddChangeObjectDTO.setEntity(new IdentifierEntity(flowChgFormView.getBaseObjectOid(), "ty.inteplm.change.CTyChangeNotice"));
//                                    this.typlmEngineeringChangeService.addBeforeChangeObjectWithStrategy(ecAddChangeObjectDTO);
//                                }
                            }

                        }
                    }

//                if (CollUtil.isNotEmpty(ecObjDataVOS)){
//                    List<ECObjData> cadDataVOS = ecObjDataVOS.stream().filter(item -> TableTypeConstrant.TY_CADDOC_OTYPE.equals(item.getOtype())).collect(Collectors.toList());
//                    List<ECObjData> docDataVOS = ecObjDataVOS.stream().filter(item -> TableTypeConstrant.TY_DOC_OTYPE.equals(item.getOtype())).collect(Collectors.toList());
//                    List<ECObjData> partDataVOS = ecObjDataVOS.stream().filter(item -> TableTypeConstrant.TY_PART_OTYPE.equals(item.getOtype())).collect(Collectors.toList());
//                    if(CollUtil.isNotEmpty(cadDataVOS)){
//                        for (ECObjData ecObjData : cadDataVOS){
//                            deleteByOidAndOtype(ecObjData.getOid(),ecObjData.getOtype(),ecObjData.getObjectNumber(),ecObjData.getIterationid());
//                        }
//                    }
//                    if(CollUtil.isNotEmpty(docDataVOS)){
//                        for (ECObjData ecObjData : docDataVOS){
//                            deleteByOidAndOtype(ecObjData.getOid(),ecObjData.getOtype(),ecObjData.getObjectNumber(),ecObjData.getIterationid());
//                        }
//                    }
//                    if(CollUtil.isNotEmpty(partDataVOS)){
//                        for (ECObjData ecObjData : partDataVOS){
//                            deleteByOidAndOtype(ecObjData.getOid(),ecObjData.getOtype(),ecObjData.getObjectNumber(),ecObjData.getIterationid());
//                        }
//                    }
//                }
                }
            }
        } catch (Exception e) {
            this.platformTransactionManager.rollback(transaction);
            throw new RuntimeException(e);
        } finally {
            TyAccountContext.setIgnoreAuth(false);
        }
        this.platformTransactionManager.commit(transaction);
    }

    public void deleteByOidAndOtype(BigInteger oid, String otype, String number, String iterationid) {
        if (TableTypeConstrant.TY_CADDOC_OTYPE.equals(otype)) {
            JSONObject docDO = null;
            if ("1".equals(iterationid)) {
                int isLatest = rtChangeMapper.judgeObjectIsLatest(RTPlmConstant.CADDOC_TABLE, String.valueOf(oid));
                if (isLatest < 1) {
                    docDO = rtChangeMapper.queryLatestCADDocByCode(number);
                }
            } else {
                docDO = rtChangeMapper.queryLatestCADDocByCode(number);
            }
            if (docDO != null) {
                DeleteDTO deleteDTO = new DeleteDTO();
                deleteDTO.setDeleteType("latestIteration");
                deleteDTO.setOid(new BigInteger(docDO.getString("OID")));
                deleteDTO.setOtype(docDO.getString("OTYPE"));
                this.commonDeleteService.productCommonDelete(Arrays.asList(deleteDTO));
                docDO = rtChangeMapper.queryLatestCADDocByCode(number);
                if (docDO != null) {
                    deleteByOidAndOtype(new BigInteger(docDO.getString("OID")), docDO.getString("OTYPE"), docDO.getString("DOCNUMBER"), docDO.getString("ITERATIONID"));
                }
            }
        } else if (TableTypeConstrant.TY_DOC_OTYPE.equals(otype)) {
            DocumentVO documentVO = null;
            if ("1".equals(iterationid)) {
                int isLatest = rtChangeMapper.judgeObjectIsLatest(RTPlmConstant.DOC_TABLE, String.valueOf(oid));
                if (isLatest < 1) {
                    documentVO = typlmDocumentService.queryLastDocByNumber(number);
                }
            } else {
                documentVO = typlmDocumentService.queryLastDocByNumber(number);
            }
            if (documentVO != null) {
                DeleteDTO deleteDTO = new DeleteDTO();
                deleteDTO.setDeleteType("latestIteration");
                deleteDTO.setOid(new BigInteger(documentVO.getOid()));
                deleteDTO.setOtype(documentVO.getOtype());
                this.commonDeleteService.productCommonDelete(Arrays.asList(deleteDTO));
                documentVO = typlmDocumentService.queryLastDocByNumber(number);
                if (documentVO != null) {
                    deleteByOidAndOtype(new BigInteger(documentVO.getOid()), documentVO.getOtype(), documentVO.getObjnumber(), documentVO.getIterationid());
                }
            }
        } else if (TableTypeConstrant.TY_PART_OTYPE.equals(otype)) {
            PartDO partDO = null;
            if ("1".equals(iterationid)) {
                int isLatest = rtChangeMapper.judgeObjectIsLatest(RTPlmConstant.PART_TABLE, String.valueOf(oid));
                if (isLatest < 1) {
                    partDO = typlmPdmPartService.queryLastPartDoByPartNumber(number);
                }
            } else {
                partDO = typlmPdmPartService.queryLastPartDoByPartNumber(number);
            }
            if (partDO != null) {
                DeleteDTO deleteDTO = new DeleteDTO();
                deleteDTO.setDeleteType("latestIteration");
                deleteDTO.setOid(partDO.getOid());
                deleteDTO.setOtype(partDO.getOtype());
                this.commonDeleteService.productCommonDelete(Arrays.asList(deleteDTO));
                partDO = typlmPdmPartService.queryLastPartDoByPartNumber(number);
                if (partDO != null) {
                    deleteByOidAndOtype(partDO.getOid(), partDO.getOtype(), partDO.getObjnumber(), partDO.getIterationid());
                }
            }
        }
    }
}